﻿
// ## 2022/12/11 # 铃 # 统合所有的运输功能的算法

namespace AI全局运输
{

	/// =========================================================================================

	const bool 调试模式 = false;
	const bool 调试模式2 = false;

	const int 分数 = 0;
	const int 金 = 1;
	const int 粮 = 2;
	const int 兵 = 3;
	const int 枪 = 4;
	const int 戟 = 5;
	const int 弩 = 6;
	const int 马 = 7;
	const int 兵器 = 8;
	const int 船 = 9;


	class Main
	{
		pk::list<pk::person @> actors;
		pk::list<pk::building @> base_list;

		Main()
		{
			pk::bind(111, pk::trigger111_t(on_turn_start));
		}

		array<int> base_goal_gold(据点_末, 1); // 据点合意金
		array<int> base_goal_food(据点_末, 1); // 据点合意粮
		array<int> base_goal_troops(据点_末, 1); // 据点合意兵
		array<int> base_goal_troops_lower(据点_末, 1); // 据点合意兵,下限,用于打破运输平衡,在城市特别多的时候也能向前运输
		array<int> to_base_trans_gold(据点_末, 0); // 运往据点的金
		array<int> to_base_trans_food(据点_末, 0); // 运往据点的粮
		array<int> to_base_trans_troops(据点_末, 0); // 运往据点的兵力

		int base_id;


		void on_turn_start(pk::force @force)
		{
			base_list = ch::get_base_list(force);
			if (pk::is_normal_force(force) and pk::get_elapsed_months() >= 3 and base_list.count >= 2)
			{
				calc_base_trans(force);
				reset_tranport(force);
			}
		}

		//------------------------------------------------------------------------------------------------------------------------------
		//                                        据点运输
		//------------------------------------------------------------------------------------------------------------------------------

		//******************************************运输前判决**************************************
		void calc_base_trans(pk::force @force)
		{
			//第一次循环,对所有据点进行赋值(不然寻找据点的时候会存在还未赋值的据点)
			for (int i = 0; i < 据点_末; i++)
			{
				array<pk::building @> src_base_arr;
				pk::building @building = pk::get_building(i);
				pk::district @district = pk::get_district(pk::get_building(i).get_district_id());
				if (building.get_force_id() != force.get_id()) continue;

				//玩家军团和电脑不同处理办法
				if (!force.is_player())
				{
					base_goal_gold[i] = pk::min(pk::get_max_gold(building), ai::force_gold[force.get_id()] * ai::base_score[i] / ai::force_score[force.get_id()]) + 500;
					base_goal_food[i] = pk::min(pk::get_max_food(building), ai::force_food[force.get_id()] * ai::base_score[i] / ai::force_score[force.get_id()]) + 3000;
					base_goal_troops[i] = pk::min(pk::get_max_troops(building), ai::force_troops_for_base[force.get_id()] * ai::base_score[i] / ai::force_score[force.get_id()]) + 500;
					base_goal_troops_lower[i] = int(base_goal_troops[i] * pk::min(pk::max(pow(0.8, ai::base_in_line_level[i]), 0.1), 1.0));


					if (i < 城市_末)
					{
						base_goal_gold[i] = pk::max(base_goal_gold[i], 2000);
						base_goal_food[i] = pk::max(base_goal_food[i], 30000);
						base_goal_troops[i] = pk::max(base_goal_troops[i], 10000);
						base_goal_troops_lower[i] = pk::max(base_goal_troops_lower[i], 6000);
					}

					if (i >= 城市_末)
					{
						base_goal_gold[i] = pk::max(base_goal_gold[i], 1000);
						base_goal_food[i] = pk::max(base_goal_food[i], 20000);
						base_goal_troops[i] = pk::max(base_goal_troops[i], 5000);
						base_goal_troops_lower[i] = pk::max(base_goal_troops_lower[i], 3000);
					}


					if (调试模式2)  pk::trace(pk::format("0{},遍历城市_势力分配,本城目标兵{},势力兵{},城市分{},势力分{},层级{},", pk::decode(pk::get_name(pk::get_building(i))), base_goal_troops[i], ai::force_troops_for_base[force.get_id()], ai::base_score[i], ai::force_score[force.get_id()], ai::base_in_line_level[i]));
					//pk::trace(pk::format("0{},遍历城市_势力分配,本城目标兵{},势力兵{},城市分{},势力分{},", pk::decode(pk::get_name(pk::get_building(i))), base_goal_troops[i], ai::force_troops_for_base[force.get_id()], ai::base_score[i], ai::force_score[force.get_id()]));


				}
				else if (force.is_player() and district !is null and district.get_id() > 0 and district.get_id() < 军团_末)
				{
					if (!district.transport) continue;
					base_goal_gold[i] = pk::min(pk::get_max_gold(building), ai::district_gold[district.get_id()] * ai::base_score[i] / ai::district_score[district.get_id()]) + 500;
					base_goal_food[i] = pk::min(pk::get_max_food(building), ai::district_food[district.get_id()] * ai::base_score[i] / ai::district_score[district.get_id()]) + 3000;
					base_goal_troops[i] = pk::min(pk::get_max_troops(building), ai::district_troops[district.get_id()] * ai::base_score[i] / ai::district_score[district.get_id()]) + 500;
					base_goal_troops_lower[i] = int(base_goal_troops[i] * pk::min(pk::max(pow(0.8, ai::base_in_line_level[i]), 0.1), 1.0));
					base_goal_troops_lower[i] = pk::max(base_goal_troops_lower[i], 6000);

				}
			}

			//第二次循环,进行计算
			for (int i = 0; i < 据点_末; i++)
			{
				array<pk::building @> src_base_arr;
				pk::building @building = pk::get_building(i);
				pk::district @district = pk::get_district(pk::get_building(i).get_district_id());
				if (building.get_force_id() != force.get_id())
					continue;
				if (pk::is_player_controlled(building))
					continue;

				if (force.is_player() and district !is null and district.get_id() > 0 and district.get_id() < 军团_末 and !district.transport)
					continue;

				bool need_gold = pk::get_gold(building) * 1.0 / base_goal_gold[i] < 0.8 or pk::get_gold(building) < ((i < 城市_末) ? 2000 : 1000);
				bool need_food = pk::get_food(building) * 1.0 / base_goal_food[i] < 0.8 or pk::get_food(building) < ((i < 城市_末) ? 20000 : 10000);
				bool need_troops = pk::get_troops(building) * 1.0 / base_goal_troops[i] < 0.8 or pk::get_troops(building) < ((i < 城市_末) ? 5000 : 3000);

				// if (!need_gold and !need_food and !need_troops)
				// 	continue;

				if (building.hp < 3000 or building.energy < 20)
					continue;

					//战斗吃紧的时候不去运输
				if (pk::enemies_around(building))
					continue;

					//战斗吃紧的时候不去运输
				if (ai::base_around_enemy_troops[i] > 10000)
					continue;


				if (调试模式2)  pk::trace(pk::format("0{},要求运输的城市城市,本城目标兵{},势力兵{},城市分{},势力分{},", pk::decode(pk::get_name(pk::get_building(i))), base_goal_troops[i], ai::force_troops_for_base[force.get_id()], ai::base_score[i], ai::force_score[force.get_id()]));



		 //玩家军团和电脑不同处理办法
				if (!force.is_player())
				{
					src_base_arr = 寻找据点(building, force, 0/*电脑势力*/);
				}

				else if (force.is_player())
				{
					src_base_arr = 寻找据点(building, force, 1/*玩家势力*/);
				}


				if (src_base_arr.length == 0) continue;

					//按实际现存的多出来的资源进行排序
				src_base_arr.sort(function(a, b)
				{
					int a_score = (pk::get_gold(a) - main.base_goal_gold[a.get_id()]) + (pk::get_food(a) - main.base_goal_food[a.get_id()]) / 10 + (pk::get_troops(a) - main.base_goal_troops_lower[a.get_id()]) * 3 + pk::get_troops(a) / 3 + ((pk::get_troops(a) == pk::get_max_troops(a)) ? 30000 : 0);
					int b_score = (pk::get_gold(b) - main.base_goal_gold[b.get_id()]) + (pk::get_food(b) - main.base_goal_food[b.get_id()]) / 10 + (pk::get_troops(b) - main.base_goal_troops_lower[b.get_id()]) * 3 + pk::get_troops(b) / 3 + ((pk::get_troops(b) == pk::get_max_troops(b)) ? 30000 : 0);
					return a_score > b_score; // 先按兵力倒序，再按武将数排序，再按id排序
				});

				运输部队出征(src_base_arr[0], building);
				//ch::remove_idle_person(context, actors);
			}
		}


		//********************* 在运输部队出发的据点接壤的自势力据点中搜寻可运输的候选据点****************

		array<pk::building @> 寻找据点(pk::building @building, pk::force @force, int type/*电脑势力*/)
		{

			array<pk::building @> src_base_arr;
			for (int i = 0; i < 据点_末; i++)
			{
				pk::building @src_base = pk::get_building(i);

				if (src_base.get_force_id() != building.get_force_id())
					continue;

				if (i == building.get_id())
					continue;

				if (ai::base_statue[i] == 据点_兵临 or ai::base_statue[i] == 据点_战斗)
					continue;

				if (!pk::is_alive(src_base))
					continue;

				if (pk::get_idle_person_list(src_base).count == 0)
					continue;

				if (调试模式2) pk::trace(pk::format("1{},寻找的城市,基础判断通过", pk::decode(pk::get_name(pk::get_building(i)))));


				pk::district @src_district = pk::get_district(src_base.get_district_id());
				pk::district @dst_district = pk::get_district(building.get_district_id());

				if (force.is_player() and type == 1)
				{
					if (src_district.no != dst_district.no and !src_district.transport and src_district.transport_building != building.get_id())
						continue;

					if (src_district.no == 1)
						continue;
				}

				if (调试模式2) pk::trace(pk::format("2{},军团判断通过,城市兵力{},目标兵力{},", pk::decode(pk::get_name(pk::get_building(i))), pk::get_troops(src_base), base_goal_troops[i]));


				int 运输据点距离上限 = 3;

				//物资太少不用考虑
				if (pk::get_troops(src_base) < base_goal_troops_lower[i])
					continue;

				int building_distance = pk::get_building_distance(building.get_id(), i, building.get_force_id());
				if (building_distance > 3) continue;

				if (调试模式2) pk::trace(pk::format("3{},物资判断通过,据点状态{},距点距离{},真实距离{}", pk::decode(pk::get_name(pk::get_building(i))), ai::base_statue[i], building_distance, unit_distance[building.get_id()][i]));



				//道路不通的情况下没办法.
				if (!ch::is_valid_routepath(i, building.get_id(), pk::get_building(i).get_force_id()))
					continue;

				if (调试模式2) pk::trace(pk::format("4{},路径判断通过,src据点状态{},dst据点状态{}", pk::decode(pk::get_name(pk::get_building(i))), ai::base_statue[i], ai::base_statue[building.get_id()]));


				//如果出发城市是前线,目标城市要至少比出发城市更危险,才能运输
				if (ai::base_statue[building.get_id()] >= ai::base_statue[i] and ai::base_statue[i] <= 据点_前线)
					continue;

				if (ai::base_statue[building.get_id()] >= ai::base_statue[i] and ai::base_statue[i] <= 据点_前线)
					continue;



				if (调试模式2) pk::trace(pk::format("5{},距点距离判断通过,", pk::decode(pk::get_name(pk::get_building(i)))));


				if (unit_distance[building.get_id()][i] > 12)
					continue;

				if (调试模式2)
				{
					pk::trace(pk::format("6{},加入待排序城市列表,", pk::decode(pk::get_name(pk::get_building(i)))));

					int score = (pk::get_gold(src_base) - base_goal_gold[i]) + (pk::get_food(src_base) - base_goal_food[i]) / 10 + (pk::get_troops(src_base) - base_goal_troops[i]) * 3;
					pk::trace(pk::format("{}运力,金{},目标金{}", pk::decode(pk::get_name(pk::get_building(i))), pk::get_gold(src_base), base_goal_gold[i]));
					pk::trace(pk::format("{}运力,粮{},目标粮{}", pk::decode(pk::get_name(pk::get_building(i))), pk::get_food(src_base), base_goal_food[i]));
					pk::trace(pk::format("{}运力,兵{},目标兵{}", pk::decode(pk::get_name(pk::get_building(i))), pk::get_troops(src_base), base_goal_troops[i]));

					pk::trace(pk::format("{}运力,总分{}", pk::decode(pk::get_name(pk::get_building(i))), score));
				}

				src_base_arr.insertLast(src_base);
			}

			return src_base_arr;
		}

		//*****************************************运输执行计算出征**************************************
		void 运输部队出征(pk::building @src_base, pk::building @dst_base)
		{
			pk::force @force = pk::get_force(src_base.get_force_id());
			int src_id = src_base.get_id();
			int dst_id = dst_base.get_id();
			pk::district @district = pk::get_district(src_base.get_district_id());
			string dst_base_name = pk::format("\x1b[1x{}\x1b[0x", pk::decode(pk::get_name(dst_base)));

			if (调试模式2)pk::trace(pk::format("4从{}到{},本城目标金{},军团金{},城市分{},军团分{}", pk::decode(pk::get_name(src_base)), pk::decode(pk::get_name(dst_base)), base_goal_gold[src_base.get_id()], ai::district_gold[district.get_id()], ai::base_score[src_base.get_id()], ai::district_score[district.get_id()]));


		// ********************出发地资源计算********************
			array<array<int>> src_goods_list = {
				{分数, 0},
				{金, 0},
				{粮, 0},
				{兵, 0},
				{枪, 0},
				{戟, 0},
				{弩, 0},
				{马, 0},
				{兵器, 0},
				{船, 0} };

			src_goods_list[兵][1] = pk::get_troops(src_base);
			src_goods_list[金][1] = pk::get_gold(src_base);
			src_goods_list[粮][1] = pk::get_food(src_base);
			src_goods_list[枪][1] = pk::get_weapon_amount(src_base, 兵器_枪);
			src_goods_list[戟][1] = pk::get_weapon_amount(src_base, 兵器_戟);
			src_goods_list[弩][1] = pk::get_weapon_amount(src_base, 兵器_弩);
			src_goods_list[马][1] = pk::get_weapon_amount(src_base, 兵器_战马);
			src_goods_list[兵器][1] = pk::get_weapon_amount(src_base, 兵器_冲车) + pk::get_weapon_amount(src_base, 兵器_井阑) + pk::get_weapon_amount(src_base, 兵器_木兽) + pk::get_weapon_amount(src_base, 兵器_投石);
			src_goods_list[船][1] = pk::get_weapon_amount(src_base, 兵器_楼船) + pk::get_weapon_amount(src_base, 兵器_斗舰);

			// 目的地资源计算
			array<array<int>> dst_goods_list = {
				{分数, 0},
				{金, 0},
				{粮, 0},
				{兵, 0},
				{枪, 0},
				{戟, 0},
				{弩, 0},
				{马, 0},
				{兵器, 0},
				{船, 0} };

			dst_goods_list[兵][1] = pk::get_troops(dst_base);
			dst_goods_list[金][1] = pk::get_gold(dst_base);
			dst_goods_list[粮][1] = pk::get_food(dst_base);
			dst_goods_list[枪][1] = pk::get_weapon_amount(dst_base, 兵器_枪);
			dst_goods_list[戟][1] = pk::get_weapon_amount(dst_base, 兵器_戟);
			dst_goods_list[弩][1] = pk::get_weapon_amount(dst_base, 兵器_弩);
			dst_goods_list[马][1] = pk::get_weapon_amount(dst_base, 兵器_战马);
			dst_goods_list[兵器][1] = pk::get_weapon_amount(dst_base, 兵器_冲车) + pk::get_weapon_amount(dst_base, 兵器_井阑) + pk::get_weapon_amount(dst_base, 兵器_木兽) + pk::get_weapon_amount(dst_base, 兵器_投石);
			dst_goods_list[船][1] = pk::get_weapon_amount(dst_base, 兵器_楼船) + pk::get_weapon_amount(dst_base, 兵器_斗舰);


			//********************把指向目标的运输队的数据加入到目标城市数组中********************
			pk::list<pk::unit @> unit_list = pk::get_unit_list(force);
			for (int i = 0; i < unit_list.count; i++)
			{
				pk::unit @unit = unit_list[i];
				if (!pk::is_alive(unit))
					continue;
				if (unit.get_force_id() != src_base.get_force_id())
					continue;
				if (unit.type != 部队类型_运输)
					continue;
				if (!pk::is_valid_base_id(unit.target) or unit.target >= 据点_末)
					continue;
				if (unit.target == dst_base.get_id())
				{
					dst_goods_list[兵][1] += unit.troops;
					dst_goods_list[金][1] += unit.gold;
					dst_goods_list[粮][1] += unit.food;
					dst_goods_list[枪][1] += unit.stock[兵器_枪].amount;
					dst_goods_list[戟][1] += unit.stock[兵器_戟].amount;
					dst_goods_list[弩][1] += unit.stock[兵器_弩].amount;
					dst_goods_list[马][1] += unit.stock[兵器_战马].amount;
					dst_goods_list[兵器][1] += unit.stock[兵器_井阑].amount + unit.stock[兵器_冲车].amount + unit.stock[兵器_木兽].amount + unit.stock[兵器_投石].amount;
					dst_goods_list[船][1] += unit.stock[兵器_斗舰].amount + unit.stock[兵器_楼船].amount;
				}
			}


				//*******************************************************对出发地打分************************************************
			src_goods_list[分数][1] = pk::max(2, ai::base_score[src_base.get_id()]);
			dst_goods_list[分数][1] = pk::max(2, ai::base_score[dst_base.get_id()]);

			if (调试模式2)	pk::trace(pk::format("{}到{} 出发分:{}，目的地分{}", pk::decode(pk::get_name(src_base)), dst_base_name, src_goods_list[分数][1], dst_goods_list[分数][1]));

				//*****************************************************计算运输量***********************************************

			//金运输量为我能提供的和对方需要的的值的最小值.
			int 金运输量 = pk::min(src_goods_list[金][1] - base_goal_gold[src_base.get_id()], base_goal_gold[dst_base.get_id()] - dst_goods_list[金][1]);

			//粮运输量为我能提供的和对方需要的的值的最小值.
			int 粮运输量 = pk::min(src_goods_list[粮][1] - base_goal_food[src_base.get_id()], base_goal_food[dst_base.get_id()] - dst_goods_list[粮][1]);

			//兵运输量为我能提供的和对方需要的的值的最小值.
			int 兵运输量 = pk::min(src_goods_list[兵][1] - base_goal_troops[src_base.get_id()], base_goal_troops[dst_base.get_id()] - dst_goods_list[兵][1]);

			//特殊情况::当后方输出城市层级>=3的时候,向前线运输使用不同的算法(即下限法,把自己能输出的全都输出走)
			if (ai::base_in_line_level[src_id] > ai::base_in_line_level[dst_id] and ai::base_in_line_level[src_id] >= 3)
			{
							//特殊情况::当后方输出城市层级>=3的时候,向前线运输使用不同的算法(即下限法,把自己能输出的全都输出走)
				粮运输量 = int(粮运输量 * pk::min(pk::max(pow(0.8, ai::base_in_line_level[src_id]), 0.1), 1.0));
				兵运输量 = src_goods_list[兵][1] - base_goal_troops_lower[src_base.get_id()];
				//if (src_id == 铃据点_辽东)pk::trace(pk::format("{}, src_goods_list{}, base_goal_troops_lower{}", pk::decode(pk::get_name(src_base)), src_goods_list[兵][1], base_goal_troops_lower[src_base.get_id()]));
			}

			if (src_id < 城市_末 and src_base.troops <= 12000)  兵运输量 = 500;
			if (src_id >= 城市_末 and src_base.troops <= 8000)  兵运输量 = 500;

			if (调试模式2)
			{
				pk::trace(pk::format("{}到{}, 出发兵:{}，出发分配兵:{}目标兵{},目的分配兵{},运兵{}", pk::decode(pk::get_name(src_base)), dst_base_name, src_goods_list[兵][1], base_goal_troops[src_base.get_id()], dst_goods_list[兵][1], base_goal_troops[dst_base.get_id()], 兵运输量));
			}

			金运输量 = pk::max(金运输量, 0);
			粮运输量 = pk::max(粮运输量, 1000);
			兵运输量 = pk::max(兵运输量, 500);


			// 如果据点兵力比较多,要提高粮留存量,1000兵25粮一个旬度,因此1年粮草为兵力/1000*25*36
			int 粮留存量 = pk::get_troops(src_base) / 1000 * 25 * 36;

			if (ai::base_statue[src_base.get_id()] == 据点_前线) 粮留存量 = 粮留存量 * 2;
			if (ai::base_statue[src_base.get_id()] == 据点_危险) 粮留存量 = 粮留存量 * 3;


			int 据点留存兵粮限制最大运输兵力 = (pk::get_food(src_base) - 粮留存量) * 10 / 2;
			兵运输量 = pk::min(兵运输量, 据点留存兵粮限制最大运输兵力);

			if (调试模式2)
			{
				pk::trace(pk::format("{}到{} 出发金:{}，目标金{},出发分配金:{}，目的分配金{},运金{}", pk::decode(pk::get_name(src_base)), dst_base_name, src_goods_list[金][1], dst_goods_list[金][1], base_goal_gold[src_base.get_id()], base_goal_gold[dst_base.get_id()], 金运输量));
				pk::trace(pk::format("{}到{} 出发粮:{}，目标粮{},出发分配粮:{}，目的分配粮{},运粮{}", pk::decode(pk::get_name(src_base)), dst_base_name, src_goods_list[粮][1], dst_goods_list[粮][1], base_goal_food[src_base.get_id()], base_goal_food[dst_base.get_id()], 粮运输量));
				pk::trace(pk::format("{}到{} 出发兵:{}，目标兵{},出发分配兵:{}，目的分配兵{},运兵{}", pk::decode(pk::get_name(src_base)), dst_base_name, src_goods_list[兵][1], dst_goods_list[兵][1], base_goal_troops[src_base.get_id()], base_goal_troops[dst_base.get_id()], 兵运输量));
			}

			// 不能撑满目标据点
			int 金运输量_最大值 = pk::max(0, pk::min(pk::get_gold(src_base), pk::get_max_gold(dst_base) - dst_goods_list[金][1])) + 1000;
			int 粮运输量_最大值 = pk::max(0, pk::min(pk::get_food(src_base), pk::get_max_food(dst_base) - dst_goods_list[粮][1])) + 兵运输量 * (unit_distance[src_base.get_id()][dst_base.get_id()] + 1) / 10;
			int 兵运输量_最大值 = pk::max(0, pk::min(pk::get_troops(src_base), pk::get_max_troops(dst_base) - dst_goods_list[兵][1])) + 1000;

			// 避免意外情况损失惨重,每次运输都不超过上限

			金运输量_最大值 = pk::min(金运输量_最大值, 50000);
			粮运输量_最大值 = pk::min(粮运输量_最大值, 100000);
			兵运输量_最大值 = pk::min(兵运输量_最大值, 50000);

			if (dst_base.get_id() >= 城市_末)
			{
				金运输量_最大值 = pk::min(金运输量_最大值, 30000);
				粮运输量_最大值 = pk::min(粮运输量_最大值, 100000);
				兵运输量_最大值 = pk::min(兵运输量_最大值, 30000);
			}

			粮运输量 = pk::min(粮运输量_最大值, 粮运输量);
			金运输量 = pk::min(金运输量_最大值, 金运输量);
			兵运输量 = pk::max(pk::min(兵运输量_最大值, 兵运输量), 500);

			//粮运输量需要有下限
			粮运输量 = pk::max(兵运输量 * (unit_distance[src_base.get_id()][dst_base.get_id()] + 1) / 10, 粮运输量);

			if (调试模式2)	pk::trace(pk::format("{}到{}金运输量：{}，粮运输量：{}，兵运输量：{}，兵运输量最大值：{}，目标预期兵：{}", pk::decode(pk::get_name(src_base)), dst_base_name, 金运输量, 粮运输量, 兵运输量, 兵运输量_最大值, dst_goods_list[兵][1]));


			pk::com_deploy_cmd_info cmd;
			@cmd.base = @src_base;
			cmd.type = 部队类型_运输;

			// 兵装运输
			int 兵装运输量 = 0;
			int 兵装留存量 = 0;
			int 兵装运输量_最大值 = 0;
			int 总兵装运输量 = 0;
			int 目标总兵装量 = 0;

			for (int weapon_id = 兵器_枪; weapon_id <= 兵器_战马; weapon_id++)
			{
				int 分配留存兵装 = (pk::get_weapon_amount(src_base, weapon_id) + pk::get_weapon_amount(dst_base, weapon_id)) * src_goods_list[分数][1] / (src_goods_list[分数][1] + dst_goods_list[分数][1]);

			//特殊情况::当后方输出城市层级>=3的时候,向前线运输使用不同的算法(即下限法,把自己能输出的全都输出走)
				if (ai::base_in_line_level[src_id] > ai::base_in_line_level[dst_id] and ai::base_in_line_level[src_id] >= 3)
					分配留存兵装 = int(分配留存兵装 * pk::min(pk::max(pow(0.8, ai::base_in_line_level[src_id]), 0.1), 1.0));

				兵装运输量 = pk::max(pk::get_weapon_amount(src_base, weapon_id) - 分配留存兵装, 0);

				兵装运输量_最大值 = pk::get_max_weapon_amount(dst_base, weapon_id) - pk::get_weapon_amount(dst_base, weapon_id);
				兵装运输量_最大值 = pk::min(兵装运输量_最大值, ((dst_base.get_id() < 城市_末) ? 50000 : 20000));

				if (兵装运输量 > 兵装运输量_最大值)
					兵装运输量 = 兵装运输量_最大值;

				if (weapon_id <= 兵器_战马 and 兵装运输量 > 3000)
				{
					总兵装运输量 += 兵装运输量;
					cmd.weapon_id[weapon_id] = weapon_id;
					cmd.weapon_amount[weapon_id] = 兵装运输量;
				}
				目标总兵装量 += dst_goods_list[weapon_id + 3][1];
			}

			// 兵装运输
			int 兵器运输量 = 0;
			int 兵器留存量 = 0;
			int 兵器运输量_最大值 = 0;

			// 暂时分开考虑,每个10000兵需要1个兵器
			兵器留存量 = int((pk::get_troops(src_base) - 兵运输量) / 10000);

			for (int weapon_id = 兵器_冲车; weapon_id <= 兵器_斗舰; weapon_id++)
			{
				if (weapon_id == 兵器_走舸)
					continue;

				int 分配留存兵器 = (pk::get_weapon_amount(src_base, weapon_id) + pk::get_weapon_amount(dst_base, weapon_id)) * src_goods_list[分数][1] / (src_goods_list[分数][1] + dst_goods_list[分数][1]);
							//特殊情况::当后方输出城市层级>=3的时候,向前线运输使用不同的算法(即下限法,把自己能输出的全都输出走)
				if (ai::base_in_line_level[src_id] > ai::base_in_line_level[dst_id] and ai::base_in_line_level[src_id] >= 3)
					分配留存兵器 = int(分配留存兵器 * pk::min(pk::max(pow(0.8, ai::base_in_line_level[src_id]), 0.1), 1.0));

				兵器运输量 = pk::max(pk::get_weapon_amount(src_base, weapon_id) - 分配留存兵器, 0);
				兵装运输量_最大值 = pk::min(兵装运输量_最大值, ((dst_base.get_id() < 城市_末) ? 5 : 2));

				兵器运输量_最大值 = pk::get_max_weapon_amount(dst_base, weapon_id) - pk::get_weapon_amount(dst_base, weapon_id);

				if (兵器运输量 > 兵器运输量_最大值)
					兵器运输量 = 兵器运输量_最大值;

				if (兵器运输量 > 3 and weapon_id != 兵器_走舸)
				{
					cmd.weapon_id[weapon_id] = weapon_id;
					cmd.weapon_amount[weapon_id] = 兵器运输量;
				}
			}

			// 运输量太少也没必要
			int 总运输价值 = 金运输量 / 2 + 粮运输量 / 10 + 兵运输量 + 总兵装运输量 / 5;

			float 金运输占比 = 1.0 * 金运输量 / pk::max(金运输量 + dst_goods_list[金][1], 1000);
			float 粮运输占比 = 1.0 * 粮运输量 / pk::max(粮运输量 + dst_goods_list[粮][1], 5000);
			float 兵运输占比 = 1.0 * 兵运输量 / pk::max(兵运输量 + dst_goods_list[兵][1], 1000);
			float 兵装运输占比 = 1.0 * 兵装运输量 / pk::max(兵装运输量 + 目标总兵装量, 5000);
			float 总运输占比 = 1.0 * 金运输占比 + 粮运输占比 + 兵运输占比 + 兵装运输占比;

			if (调试模式2)  pk::trace(pk::format("{}到{}前置执行:金运输量：{}，粮运输量：{}，兵运输量：{},兵装运输量：{}，总运输价值：{},总运输占比：{}", pk::decode(pk::get_name(src_base)), dst_base_name, 金运输量, 粮运输量, 兵运输量, 兵装运输量, 总运输价值, 总运输占比));

			if ((总运输价值 < 3000 or 总运输占比 < 1) and 总运输价值 < 20000 and 兵运输量 < 5000)
				return;

			if (调试模式2)	pk::trace(pk::format("{}到{}后置执行:金运输量：{}，粮运输量：{}，兵运输量：{},兵装运输量：{}，总运输价值：{},总运输占比：{}", pk::decode(pk::get_name(src_base)), dst_base_name, 金运输量, 粮运输量, 兵运输量, 兵装运输量, 总运输价值, 总运输占比));


			//********************选择武将*******************
			pk::list<pk::person @> person_list = pk::get_idle_person_list(src_base);
			person_list.sort(function(a, b) {
				int a_skill = pk::has_skill(a, 特技_运输) ? 10000 : 0;
				int b_skill = pk::has_skill(b, 特技_运输) ? 10000 : 0;
				return ((a_skill)-int(a.kouseki) / 100) > ((b_skill)-int(b.kouseki) / 100);
			});

			cmd.member[0] = person_list[0].get_id();

			actors.add(person_list[0]);


			//********************运输队出征*******************
			cmd.food = 粮运输量;
			cmd.gold = 金运输量;
			cmd.troops = 兵运输量;
			cmd.order = 部队任务_移动;
			cmd.target_pos = dst_base.pos;
			int unit_id = pk::command(cmd);

			if (unit_id != -1)
			{
				pk::unit @unit = pk::get_unit(unit_id);
				unit.action_done = true;

				if (调试模式)
				{
					string unit_name3 = pk::format("\x1b[1x{}\x1b[0x", pk::decode(pk::get_name(unit)));
					string src_base_name = pk::format("\x1b[1x{}\x1b[0x", pk::decode(pk::get_name(src_base)));
					string dst_base_name2 = pk::format("\x1b[1x{}\x1b[0x", pk::decode(pk::get_name(dst_base)));
					string action_message = pk::format("运输调度:{}从{}运输到{}", unit_name3, src_base_name, dst_base_name2);
					pk::trace(action_message);
				}
			}
		}



	//------------------------------------------------------------------------------------------------------------------------------
	//                                            运输队变更
	//------------------------------------------------------------------------------------------------------------------------------

	//*********************************************查找需要变更的运输队**************************************
		void reset_tranport(pk::force @force)
		{
			if (!pk::is_normal_force(force) or force.get_id() >= 势力_末 or force.get_id() < 0)
				return;

			pk::list<pk::unit @> unit_list = pk::get_unit_list(force);
			for (int i = 0; i < unit_list.count; i++)
			{
				pk::unit @unit = unit_list[i];
				if (!pk::is_alive(unit))
					continue;

				//  跳过非运输类型部队
				if (unit.type != 部队类型_运输)
					continue;

				if (pk::is_player_controlled(unit))
					continue;

				if ((unit.order == 部队任务_待命))
				{
					重设运输队目标(unit);
					continue;
				}

				if ((unit.target_type == 部队任务对象_据点) and pk::is_valid_base_id(unit.target) and unit.target < 据点_末)
				{
					if (unit.troops + pk::get_troops(pk::get_building(unit.target)) > pk::get_max_troops(pk::get_building(unit.target)) + 1000) //允许1000的冗余
						重设运输队目标(unit);
					continue;
				}
			}
		}

		//*********************************************变更运输队目标**************************************
		void 重设运输队目标(pk::unit @unit)
		{

			array<pk::building @> dst_base_arr = 获取运输队据点列表(unit);
			int dst_id;

			if (!pk::is_valid_person_id(unit.member[0])) return;

			if (dst_base_arr.length == 0)
			{
				pk::person@ leader = pk::get_person(unit.leader);
				dst_id = leader.service;
				if (dst_id < 0 or dst_id >据点_末)
					return;
				pk::set_order(unit, 部队任务_撤退, pk::get_building(leader.service).pos);
			}

			else
			{
				// 运输候选据点的优先顺序
				dst_base_arr.sort(function(a, b) { return ai::base_in_line_score[a.get_id()] > ai::base_in_line_score[b.get_id()]; });
				dst_id = dst_base_arr[0].get_id();

				pk::set_order(unit, 部队任务_补给, pk::get_building(dst_id).pos);
				if (unit.action_done == false) pk::run_order(unit);
				pk::set_action_done(unit, true);
			}

			pk::building @dst_base = pk::get_building(dst_id);

			if (pk::is_valid_person_id(unit.leader) and 调试模式)
			{
			//	pk::trace(pk::format("{}运输队ID,主将ID{}{}{}", unit.get_id(),unit.member[0],unit.member[1],unit.member[2]));

				string unit_name2 = pk::format("\x1b[1x{}\x1b[0x", pk::decode(pk::get_name(pk::get_person(unit.leader))));
				string dst_base_name2 = pk::format("\x1b[1x{}\x1b[0x", pk::decode(pk::get_name(dst_base)));
				string action_message = pk::format("{}运输队修改运输任务到{}", unit_name2, dst_base_name2);
				pk::trace(action_message);
			}
			return;
		}

		//*********************************************运输队变更的目标的时候,查找据点**************************************
		array<pk::building @> 获取运输队据点列表(pk::unit @unit)
		{

			array<pk::building @> dst_base_arr;
			for (int i = 0; i < 据点_末; i++)
			{

				pk::building @dst_base = pk::get_building(i);

				if (!pk::is_alive(dst_base))
					continue;

				//满的据点跳过
				if (pk::get_troops(dst_base) + unit.troops > pk::get_max_troops(dst_base) + 1000)//允许1000的冗余
					continue;

				//太远不行
				if (pk::get_distance(dst_base.pos, unit.pos) > 30)
					continue;

				//判断势力
				if (dst_base.get_force_id() != unit.get_force_id())
					continue;

				dst_base_arr.insertLast(dst_base);
			}

			return dst_base_arr;
		}



	} Main main;

}